using System;
using System.Collections.Generic;
using System.IO;
using System.Data;
using System.Windows.Forms;
using FileServerDocumenter.Library;

namespace FileServerDocumenter
{
    static class Program
    {
        static List<FileInfo> _myMDBList;
        static List<FileInfo> _myFileList;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new frmMain());
            //DocumentMDB();
            //DocumentShares();

            //Console.WriteLine("Process Complete");
            //Console.ReadLine();
        }

        public static void DocumentShares(String ServerName, String OutputFilePath, String SecurityOutputPath,
                Boolean IncludeDirectorySize, Boolean IncludeSecurity)
        {
            //get the directores which to scan
            List<DirectoryInfo> myDirectories = getServerShares(ServerName);
            //List<DirectoryInfo> myDirectories = getTestShares(server);

            Library.Util.DirectoryInfoToFile(myDirectories, OutputFilePath, SecurityOutputPath, 
                    IncludeDirectorySize, false, IncludeSecurity);
        }

        public static void DocumentSubDirectories(String Path, String OutputFilePath, String SecurityOutputPath,
                Boolean IncludeDirectorySize, Boolean IncludeSecurity)
        {

            //get the directores which to scan
            List<DirectoryInfo> myDirectories = getSubDirectories(Path);

            Library.Util.DirectoryInfoToFile(myDirectories, OutputFilePath, SecurityOutputPath,
                    IncludeDirectorySize, false, IncludeSecurity);
        }

        public static void DocumentFiles(String Path, String FileExtension, Boolean IsServer)
        {
            List<DirectoryInfo> myDirectories;

            //get the directores which to scan
            if (IsServer)
            {
                myDirectories = getServerShares(Path);
                //List<DirectoryInfo> myDirectories = getTestShares(ServerName);
            }
            else
            { 
                myDirectories = new List<DirectoryInfo>();
                myDirectories.Add(new DirectoryInfo(Path));
            }            

            _myFileList = new List<FileInfo>();

            //scan the network shares to get a list of files
            buildListOfFiles(myDirectories, FileExtension);

            //load it into cache
            DataTable dt = getSchemaTable();

            IterateResults(_myFileList, dt);

            Library.DataCache dc = Library.DataCache.GetInstance();

            dc.CacheData(dt);
        }

        private static void DocumentMDB()
        {
            Console.Write("Enter the NetBios name of a server on your network: ");
            string server = Console.ReadLine();

            //get the directores which to scan
            List<DirectoryInfo> myDirectories = getServerShares(server);
            //List<DirectoryInfo> myDirectories = getTestShares(server);

            _myMDBList = new List<FileInfo>();

            //scan the network shares to get a list of mdbs
            buildListOfMdbs(myDirectories);

            //load it into cache
            DataTable dt = getSchemaTable();

            IterateResults(_myMDBList,dt);

            Library.DataCache dc = Library.DataCache.GetInstance();

            dc.CacheData(dt);
        }

        private static List<DirectoryInfo> getTestShares(string ServerName)
        {
            List<DirectoryInfo> myList = new List<DirectoryInfo>();

            myList.Add(new DirectoryInfo("\\\\server1\\share"));

            return myList;
        }

        private static List<DirectoryInfo> getSubDirectories(string Path)
        {
            List<DirectoryInfo> myList = new List<DirectoryInfo>();

            DirectoryInfo di = new DirectoryInfo(Path);

            foreach (DirectoryInfo subDI in di.GetDirectories())
            {
                myList.Add(subDI);
            }

            return myList;
        }

        private static List<DirectoryInfo> getServerShares(string ServerName)
        {
            List<DirectoryInfo> myList = new List<DirectoryInfo>();

            // Enumerate shares on a remote computer
            if (ServerName != null && ServerName.Trim().Length > 0)
            {     
                ShareCollection shi = ShareCollection.GetShares(ServerName);
                if (shi != null)
                {
                    foreach (Share si in shi)
                    {
                        // If this is a file-system share, try to list the first five subfolders.
                        // NB: If the share is on a removable device, you could get "Not ready" or "Access denied" exceptions.
                        // If you don't have permissions to the share, you will get security exceptions.
                        if (si.IsFileSystem)
                        {
                            try
                            {
                                System.IO.DirectoryInfo di = si.Root;
                                //System.IO.DirectoryInfo[] Flds = d.GetDirectories();

                                myList.Add(di);
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("\tError listing {0}:\n\t{1}\n",
                                    si.ToString(), ex.Message);
                            }
                        }
                    }
                }
                else
                    Console.WriteLine("Unable to enumerate the shares on {0}.\n"
                        + "Make sure the machine exists, and that you have permission to access it.",
                        ServerName);

                Console.WriteLine();
            }

            return myList;
        }

        private static void buildListOfFiles(List<DirectoryInfo> myDirectories, String FileExtension)
        {
            foreach (DirectoryInfo di in myDirectories)
            {
                SearchforFiles(di, FileExtension);
            }
        }

        private static void buildListOfMdbs(List<DirectoryInfo> myDirectories)
        {
            foreach (DirectoryInfo di in myDirectories)
            {
                SearchforMDBs(di);
            }
        }

        private static void SearchforFiles(DirectoryInfo myDirectory, String FileExtension)
        {
            try
            {
                // find any filess
                FileInfo[] files = myDirectory.GetFiles("*." + FileExtension);

                foreach (FileInfo fi in files)
                {
                    _myFileList.Add(fi);
                    Console.WriteLine(fi.FullName);
                }

                //loop through the dirs
                DirectoryInfo[] dirs = myDirectory.GetDirectories();

                foreach (DirectoryInfo di in dirs)
                {
                    //recursive
                    SearchforFiles(di,FileExtension);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("\tError listing {0}:\n\t{1}\n",
                    myDirectory.FullName, ex.Message);
            }
        }

        private static void SearchforMDBs(DirectoryInfo myDirectory)
        {
            try
            {
                // find any mdbs
                FileInfo[] files = myDirectory.GetFiles("*.mdb");

                foreach (FileInfo fi in files)
                {
                    _myMDBList.Add(fi);
                    Console.WriteLine(fi.FullName);
                }
                
                //loop through the dirs
                DirectoryInfo[] dirs = myDirectory.GetDirectories();

                foreach (DirectoryInfo di in dirs)
                {
                    //recursive
                    SearchforMDBs(di);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("\tError listing {0}:\n\t{1}\n",
                    myDirectory.FullName, ex.Message);
            }
        }

        private static void IterateResults(List<FileInfo> myFileInfoList, System.Data.DataTable TargetDataTable)
        {
            foreach (FileInfo fi in myFileInfoList)
            {
                DataRow dr = TargetDataTable.NewRow();
      
                dr["Name"] = fi.Name;
                dr["FullName"] = fi.FullName;
                dr["CreationTime"] = fi.CreationTime;
                dr["LastAccessTime"] = fi.LastAccessTime;
                dr["Length"] = fi.Length;
                dr["AsOfDate"] = DateTime.Today;

                TargetDataTable.Rows.Add(dr);
            }
        }

        //private static void
        private static System.Data.DataTable getSchemaTable()
        {
            System.Data.DataTable dt = new System.Data.DataTable();

            dt.Columns.Add("Name");
            dt.Columns.Add("FullName");
            dt.Columns.Add("CreationTime");
            dt.Columns.Add("LastAccessTime");
            dt.Columns.Add("Length");
            dt.Columns.Add("AsOfDate");

            return dt;
        }
    }
}